/*
 * Copyright 2010 Dovado FZ-LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.dovado.dovadoremote;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

public class Homeautomation extends Activity {
	class WorkingQueue extends AsyncTask<String, String, String> {

		@Override
		protected String doInBackground(String... params) {
			/*
			 * Split up the string to show popup saying "executing lamp on"
			 */
			String message[] = params[0].split(" ", 4);
			publishProgress(getResources().getString(R.string.executing) + " "
					+ message[2] + " " + message[3]);

			/*
			 * connect
			 */
			if (!Communicator.connect()) {
				return (getResources().getString(R.string.connectfail));
			}
			/*
			 * if we couldn't login then show a message explaining why:
			 */
			if (!Communicator.login()) {
				Communicator.sendCommand("quit");
				Communicator.closeConnection();
				return (Communicator.getLoginMessage());
			}

			/*
			 * We are logged in. Send the command and then quit:
			 */
			Communicator.sendCommand(params[0]);
			Communicator.sendCommand("quit");
			Communicator.closeConnection();

			/*
			 * Wait a couple of seconds to be sure that all connections are down
			 */
			try {
				Thread.sleep(3500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			return getResources().getString(R.string.doneexecuting);

		}

		@Override
		protected void onPostExecute(String result) {

			try {
				myProgressDialog.dismiss();
			} catch (Exception e) {
				// Yeah, we should do something here
			}
			/*
			 * show execution result (successful, unable to connect, etc..):
			 */
			Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG)
					.show();
		}

		@Override
		protected void onProgressUpdate(String... values) {

			try {
				// myProgressDialog.dismiss();
			} catch (Exception e) {

			}
			myProgressDialog = ProgressDialog.show(Homeautomation.this,
					getResources().getString(R.string.waitheadline), values[0],
					true);
		}
	}

	/*
	 * Definitions for alias types
	 */
	private static final int TYPE_REGULAR_ALIAS = 0;
	private static final int TYPE_GROUP = 1;

	private static final int TYPE_DIM_ALIAS = 2;
	/*
	 * A lot of arraylists and other stuff we need in order to display all the
	 * seekbars for the devices This could be improved significantly by making a
	 * matrix instead of having separate arrays for aliases, seekbars and texts
	 */
	private int seekBarProgress;
	SeekBar mSeekBar;
	TextView mProgressText;
	TextView mTrackingText;
	static ArrayList<String> aliases = new ArrayList<String>();
	static ArrayList<String> groups = new ArrayList<String>();
	static ArrayList<String> dimmeraliases = new ArrayList<String>();
	static ArrayList<SeekBar> aliasSeekBars = new ArrayList<SeekBar>();
	static ArrayList<SeekBar> groupSeekBars = new ArrayList<SeekBar>();
	static ArrayList<SeekBar> dimmerSeekBars = new ArrayList<SeekBar>();
	static ArrayList<TextView> aliasSeekBarTexts = new ArrayList<TextView>();
	static ArrayList<TextView> groupSeekBarTexts = new ArrayList<TextView>();
	static ArrayList<TextView> dimmerSeekBarTexts = new ArrayList<TextView>();
	/*
	 * Our margins. TODO: take these from dimen.xml
	 */
	final static int horizontal_margin = 0;

	final static int vertical_margin = 15;
	/*
	 * The progress-dialog which will be shown after releasing a seekbar
	 */
	ProgressDialog myProgressDialog;

	LinearLayout lx;

	/*
	 * What happens when you interact with a seekbar that belongs to a regular
	 * alias:
	 */
	private SeekBar.OnSeekBarChangeListener aliasSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			seekBarProgress = progress;
		}

		public void onStartTrackingTouch(SeekBar seekBar) {

		}

		/*
		 * When the user releases the seekbar, put the value back to 50 (middle
		 * value) and display a progress dialog
		 */
		public void onStopTrackingTouch(SeekBar seekBar) {

			String alias = aliases.get(seekBar.getId());
			/*
			 * Turn on if progress was more than 50 and off if less than 50
			 */
			if (seekBarProgress < 50) {
				sendCommand("ts turn " + alias + " " + "off");
				System.err.println("ts turn " + alias + " " + "off");
			} else {
				sendCommand("ts turn " + alias + " " + "on");
				System.err.println("ts turn " + alias + " " + "on");
			}

			/*
			 * set seekbar progress down to 50.
			 */

			seekBar.setProgress(50);

		}
	};

	/*
	 * What happens when you interact with a seekbar that belongs to a group
	 * (more or less same as for a regular alias):
	 */
	private SeekBar.OnSeekBarChangeListener groupSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			seekBarProgress = progress;
		}

		public void onStartTrackingTouch(SeekBar seekBar) {

		}

		/*
		 * When the user releases the seekbar, put the value back to 50 (middle
		 * value) and display a progress dialog
		 */
		public void onStopTrackingTouch(SeekBar seekBar) {

			String alias = groups.get(seekBar.getId());
			/*
			 * Turn on if progress was more than 50 and off if less than 50
			 */
			if (seekBarProgress < 50) {
				sendCommand("ts turn " + alias + " " + "off");
			} else {
				sendCommand("ts turn " + alias + " " + "on");
			}

			/*
			 * set seekbar progress down to 50.
			 */

			seekBar.setProgress(50);

		}
	};

	/*
	 * What happens when you interact with a seekbar that belongs to a
	 * dimmeralias:
	 */
	private SeekBar.OnSeekBarChangeListener dimmerSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			/*
			 * save the current progress so that we know where the user released
			 * the finger
			 */
			seekBarProgress = progress;
		}

		/*
		 * We do nothing special when we start tracking (so this function can be
		 * removed, but I'll leave it if anyone wants to add something):
		 */
		public void onStartTrackingTouch(SeekBar seekBar) {

		}

		/*
		 * When we release the finger we sent the command (the api accept all
		 * integers from 0-100):
		 */
		public void onStopTrackingTouch(SeekBar seekBar) {
			String alias = dimmeraliases.get(seekBar.getId());

			/*
			 * send the DIM command (eg 'ts dim bedroomlamp 80'):
			 */
			sendCommand("ts dim " + alias + " " + seekBarProgress);
			/*
			 * set seekbar progress down to 0. Pretty bad since the user has no
			 * easy way if turning the seekbar down to 0 when it's already there
			 */

			seekBar.setProgress(0);

		}
	};

	/*
	 * add an entry to array of aliases which should have seekbars
	 */
	public void add(String name, int type) {
		switch (type) {
		case TYPE_REGULAR_ALIAS:
			aliases.add(name);
			break;
		case TYPE_GROUP:
			groups.add(name);
			break;
		case TYPE_DIM_ALIAS:
			dimmeraliases.add(name);
			break;
		}
	}

	/*
	 * Displays an alertbox TODO: remove. we don't need this (popups are
	 * annoying)
	 */
	protected void alertbox(String title, String mymessage) {
		new AlertDialog.Builder(this).setMessage(mymessage).setTitle(title)
				.setCancelable(true).setNeutralButton(android.R.string.ok,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int whichButton) {
							}
						}).show();
	}

	/*
	 * Initializes the graphics
	 */
	void initialize(String in_from) {
		/*
		 * Add seekbars for each added alias
		 */

		/*
		 * We have a couple of different layouts:
		 */
		LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
		LinearLayout.LayoutParams layoutParamsWithMargin = new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
		LinearLayout.LayoutParams headlineLayoutParams = new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
		lx = (LinearLayout) findViewById(R.id.LinearLayout01);
		/*
		 * Give a 100px margin for scrolling:
		 */
		layoutParams.bottomMargin = vertical_margin / 2;
		layoutParams.rightMargin = 100;

		headlineLayoutParams.bottomMargin = vertical_margin;
		headlineLayoutParams.topMargin = vertical_margin;
		headlineLayoutParams.rightMargin = 100;

		layoutParamsWithMargin.rightMargin = 100;

		lx.removeAllViews();

		/*
		 * clear all the drawn objects from view :
		 */
		aliasSeekBarTexts.clear();
		aliasSeekBars.clear();
		groupSeekBarTexts.clear();
		groupSeekBars.clear();
		dimmerSeekBarTexts.clear();
		dimmerSeekBars.clear();

		lx.setOrientation(LinearLayout.VERTICAL);

		if (DAAPP.getHasSynced()
				&& (Communicator.getRouterModel().contains("4GR") || Communicator
						.getRouterModel().contains("UMR"))) {
			/*
			 * Bad code coming up. the three cases (regular, group, dim) should
			 * be merged into one
			 */

			/*
			 * ADD REGULAR ALIASES :
			 */
			int i = 0;
			/*
			 * for each added alias, do:
			 */
			if (aliases.size() >= 1) {
				TextView aliasText = new TextView(this);
				aliasText.setText("Regular devices");
				aliasText.setTextAppearance(this, R.style.routerlabels);
				aliasText.setTextSize(16);
				lx.addView(aliasText, headlineLayoutParams);
			}
			while (i < aliases.size()) {
				/*
				 * System.err.println("adding seekBar for " + i + " for alias "
				 * + aliases.get(i));
				 */

				/*
				 * Add a textview with aliasname for each seekbar and set
				 * correct formatting
				 */

				aliasSeekBarTexts.add(new TextView(this));
				aliasSeekBarTexts.get(i).setTextColor(
						getResources().getColor(R.color.bodytext));
				aliasSeekBarTexts.get(i).setText(aliases.get(i));
				aliasSeekBarTexts.get(i).setWidth(
						getWindowManager().getDefaultDisplay().getWidth());
				aliasSeekBarTexts.get(i).setTextAppearance(
						getApplicationContext(), R.style.alias);

				try {
					lx
							.addView(aliasSeekBarTexts.get(i),
									layoutParamsWithMargin);

				} catch (Exception e) {
					e.printStackTrace();
				}

				/*
				 * Add on/off labels for each alias:
				 */
				lx.addView(View.inflate(this, R.layout.on_label, null));

				/*
				 * We add seekBar to our array of seekbars and to Layout:
				 */

				aliasSeekBars.add((SeekBar) View.inflate(this,
						R.layout.dovadoslider, null));
				aliasSeekBars.get(i).setOnSeekBarChangeListener(
						aliasSeekBarChangeListener);

				/*
				 * Seekbar properties:
				 * 
				 * Set progress to middle (50/100):
				 */
				aliasSeekBars.get(i).setProgress(50);

				/*
				 * set ID by index number
				 */
				aliasSeekBars.get(i).setId(i);

				try {
					layoutParams.bottomMargin = 0;
					lx.addView(aliasSeekBars.get(i), layoutParams);
				} catch (Exception e) {
					e.printStackTrace();
				}
				i++;
			}

			/*
			 * ADD GROUPS
			 */
			i = 0;
			/*
			 * for each added group-alias, do:
			 */
			if (groups.size() >= 1) {
				TextView groupText = new TextView(this);
				groupText.setText("Group devices");
				groupText.setTextAppearance(this, R.style.routerlabels);
				groupText.setTextSize(16);
				lx.addView(groupText, headlineLayoutParams);
			}
			while (i < groups.size()) {

				/*
				 * Add a textview with group-aliasname for each seekbar:
				 */
				groupSeekBarTexts.add(new TextView(this));
				groupSeekBarTexts.get(i).setTextColor(
						getResources().getColor(R.color.bodytext));
				groupSeekBarTexts.get(i).setText("Group: " + groups.get(i));
				groupSeekBarTexts.get(i).setTextAppearance(
						getApplicationContext(), R.style.alias);
				try {
					lx
							.addView(groupSeekBarTexts.get(i),
									layoutParamsWithMargin);
				} catch (Exception e) {
					e.printStackTrace();
				}

				/*
				 * Add on/off labels for each group:
				 */
				lx.addView(View.inflate(this, R.layout.on_label, null));

				/*
				 * We add seekBar to our array of seekbars and to Layout:
				 */
				groupSeekBars.add((SeekBar) View.inflate(this,
						R.layout.dovadoslider, null));
				groupSeekBars.get(i).setOnSeekBarChangeListener(
						groupSeekBarChangeListener);
				/*
				 * seekbar properties:
				 * 
				 * Set progress to middle (50/100)
				 */
				groupSeekBars.get(i).setProgress(50);

				/*
				 * set ID by index number
				 */
				groupSeekBars.get(i).setId(i);
				try {
					lx.addView(groupSeekBars.get(i), layoutParams);
				} catch (Exception e) {
					e.printStackTrace();
				}

				i++;
			}

			/*
			 * ADD DIMMERS
			 */
			i = 0;
			if (dimmeraliases.size() >= 1) {
				TextView dimText = new TextView(this);
				dimText.setText("Dimmer devices");
				dimText.setTextAppearance(this, R.style.routerlabels);
				dimText.setTextSize(16);
				lx.addView(dimText, headlineLayoutParams);
			}
			/*
			 * for each added dimmer, do:
			 */
			while (i < dimmeraliases.size()) {
				/*
				 * System.err.println("adding seekBar for " + i +
				 * " for dimmeralias " + dimmeraliases.get(i));
				 */

				/*
				 * Add a textview with aliasname for each seekbar:
				 */
				dimmerSeekBarTexts.add(new TextView(this));
				dimmerSeekBarTexts.get(i).setTextColor(
						getResources().getColor(R.color.bodytext));
				dimmerSeekBarTexts.get(i).setTextAppearance(
						getApplicationContext(), R.style.alias);

				dimmerSeekBarTexts.get(i).setText(
						"Dimmer: " + dimmeraliases.get(i));

				try {
					lx.addView(dimmerSeekBarTexts.get(i),
							layoutParamsWithMargin);
				} catch (Exception e) {
					e.printStackTrace();
				}

				/*
				 * Add 0-100% for each dimmer:
				 */
				lx.addView(View.inflate(this, R.layout.dim_label, null));

				/*
				 * We add seekBar to our array of seekbars and to Layout:
				 */
				dimmerSeekBars.add((SeekBar) View.inflate(this,
						R.layout.dovadoslider, null));
				dimmerSeekBars.get(i).setOnSeekBarChangeListener(
						dimmerSeekBarChangeListener);
				/*
				 * seekbar properties:
				 * 
				 * Set progress to zero
				 */
				dimmerSeekBars.get(i).setProgress(0);

				/*
				 * set ID by index number:
				 */
				dimmerSeekBars.get(i).setId(i);
				try {
					lx.addView(dimmerSeekBars.get(i), layoutParams);
				} catch (Exception e) {
					e.printStackTrace();
				}

				i++;
			}
		} else if (Communicator.getRouterModel().contains("3GN")) {
			/*
			 * Show "Homeautomation not supported on 3GN" NOTE: We will never
			 * come here since we cannot connect to a 3GN
			 */
			if (in_from.contains("fromresume")) {
				alertbox("Not available", getResources().getString(
						R.string.automation_notsupported));
			}
			aliasSeekBarTexts.add(new TextView(this));
			aliasSeekBarTexts.get(0).setTextColor(
					getResources().getColor(R.color.bodytext));
			aliasSeekBarTexts.get(0).setText(
					getResources().getString(R.string.automation_notsupported));
			aliasSeekBarTexts.get(0).setWidth(
					getWindowManager().getDefaultDisplay().getWidth());
			try {
				lx.addView(aliasSeekBarTexts.get(0), layoutParams);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			/*
			 * Show not connected to router:
			 */
			/*
			 * if (in_from.contains("fromresume")){ alertbox("Not available",
			 * getResources().getString(R.string.automation_notconnected)); }
			 */
			aliasSeekBarTexts.add(new TextView(this));
			aliasSeekBarTexts.get(0).setTextColor(
					getResources().getColor(R.color.bodytext));
			aliasSeekBarTexts.get(0).setText(
					getResources().getString(R.string.automation_notconnected));
			aliasSeekBarTexts.get(0).setWidth(
					getWindowManager().getDefaultDisplay().getWidth());
			try {
				lx.addView(aliasSeekBarTexts.get(0), layoutParams);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.homeautomation);

		/*
		 * Put graphics on screen:
		 */
		initialize("fromoncreate");

	}

	/*
	 * If the user presses the 'back'-button (we can add some more functionality
	 * here
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			Intent i = new Intent();
			i.setAction(Intent.ACTION_MAIN);
			i.addCategory(Intent.CATEGORY_HOME);
			this.startActivity(i);
			return true;
		}
		return false;
	}

	/*
	 * We need pause/resume to reload aliases whenever sync has been pressed
	 * TODO: remove. This doesn't do anything
	 */
	@Override
	public void onPause() {
		super.onPause();
	}

	/*
	 * Re-initialize on each resume
	 */
	@Override
	public void onResume() {
		super.onResume();
		initialize("fromresume");

	}

	/*
	 * Standard window-focus override. Notice focus lost so we can pause on
	 * focus lost. e.g. user switches to take a call.
	 */
	@Override
	public void onWindowFocusChanged(boolean hasWindowFocus) {
		if (hasWindowFocus) {
			initialize("fromfocuschanged");
		}
	}

	/*
	 * When re-syncing, remove all aliases and so on
	 */
	public void removeAll() {
		aliases.clear();
		groups.clear();
		dimmeraliases.clear();
	}

	/*
	 * When sending a command, put it in the worker-queue and let the AsyncTask
	 * handle it
	 */
	private void sendCommand(String cmd) {
		new WorkingQueue().execute(cmd, "", "");
	}
}
